home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / polyview / plyvw102.lha / PolyView1.02 / pvfuncs.c < prev    next >
C/C++ Source or Header  |  1990-11-13  |  13KB  |  759 lines

  1. /* INCLUDE FILES */
  2. #include "pv.h"
  3.  
  4. int reset_c(char *);
  5. int step_c(char *);
  6. int twist_c(char *);
  7. int write_c(char *);
  8.  
  9. parse_t commands[] = {
  10.     "from", from_c,
  11.     "at", at_c,
  12.  
  13.     "step", step_c,
  14.     "twist", twist_c,
  15.     "write", write_c,
  16.     "reset", reset_c,
  17.     
  18.     NULL, NULL
  19. };
  20.  
  21.  
  22. void
  23. init_menus()
  24. {
  25.     void exit(int);
  26.  
  27.  
  28.     /* Define the window pop-up menus */
  29.     quit_m = defpup("Confirm%t|Yes, really! %f|No, not really.", exit);
  30.     vrender_m = defpup("points%f|lines%f|polygons%f",
  31.               point_mode, lines_mode, polygon_mode);
  32.     vshade_m = defpup("constant%f|gouraud%f", constant_mode, gouraud_mode);
  33.     vproject_m = defpup("perspective%f|orthographic%f", persp_mode,
  34.          ortho_mode);
  35.     vpalette_m = defpup("from file %F|gray|rainbow|rgb",
  36.                 palette_pick);
  37.     voverlay_m = defpup("at point%f|axes%f|box%f|labels%f|outlines%f",
  38.         at_point_tgl, axes_tgl, box_tgl, labels_tgl, outlines_tgl);
  39.     vanimate_m = defpup("reverse%f|reverse 1%f|stop%f|forward 1%f|forward%f",
  40.                 reverse, reverse1, stop, forward1, forward);
  41.     view_m = defpup("View %t|project %m|draw %m|shade %m|palette %m|overlay %m%l|Animate %m|Fly|Pop|Redraw|Reset|Write HDF %l|quit %m",
  42.             vproject_m, vrender_m, vshade_m, vpalette_m, voverlay_m,
  43.             vanimate_m, quit_m);
  44. }
  45.  
  46.  
  47. int
  48. parse_and_exec(command, line)
  49.     parse_t command[];
  50.     char * line;
  51. {
  52.     char word[MAXLINELEN];
  53.     char subline[MAXLINELEN];
  54.     int i;
  55.     int (*parse_fn)();
  56.  
  57.     /* Parse the command word and the rest of the line */
  58.     word[0] = '\0';
  59.     subline[0] = '\0';
  60.     sscanf(line, "%s %[^\n]", word, subline);
  61.  
  62.     /* Search for any matches of the command word */
  63.     parse_fn = NULL;
  64.     for (i = 0; command[i].word != NULL; i++) {
  65.         if (strcasecmp(command[i].word, word) == 0) {
  66.             if (parse_fn == NULL) {
  67.                 parse_fn = command[i].parse_fn;
  68.             }
  69.             else {
  70.                 return TRUE;    /* ERROR:  not unique */
  71.             }
  72.         }
  73.     }
  74.  
  75.  
  76.     /* Call the sub-line parsing function if one was found. */
  77.     if (parse_fn != NULL) {
  78.         return ((*parse_fn)(subline));
  79.     }
  80.     else {
  81.         return TRUE;
  82.     }
  83. }
  84.  
  85.  
  86. int
  87. from_c(line)
  88.     char * line;
  89. {
  90.     char word[MAXLINELEN];
  91.     windat_t * window;
  92.  
  93.     float dx, dy, dz, dt;
  94.     double fx, fy, fz, ft;
  95.     double twistf;
  96.  
  97.     double dist;
  98.     float steps;
  99.     int num_args;
  100.  
  101.  
  102.     /* Get the type of move and coordinate vector */
  103.     word[0] = '\0';
  104.     num_args = sscanf(line, "%s %f %f %f %f", word, &dx, &dy, &dz, &dt);
  105.     if ((num_args != 4) && (num_args != 5)) {
  106.         printf("syntax error:  from type x y z [twist]\n");
  107.         return TRUE;
  108.     }
  109.  
  110.  
  111.     /* The default value for twist is the current value */
  112.     if (num_args == 4) {
  113.         dt = (float) twist;
  114.     }
  115.     else {
  116.         dt *= 10;
  117.     }
  118.  
  119.  
  120.     /* Adjust the new vector based on the type (absolute or relative) */
  121.     /* and save their final values */
  122.     if (strncasecmp("abs", word, strlen(word)) == 0) {
  123.         fx = dx;
  124.         fy = dy;
  125.         fz = dz;
  126.         ft = dt;
  127.  
  128.         dx -= from[X];
  129.         dy -= from[Y];
  130.         dz -= from[Z];
  131.         dt -= twist;
  132.     }
  133.     else {
  134.         fx = dx + from[X];
  135.         fy = dy + from[Y];
  136.         fz = dz + from[Z];
  137.         ft = dt + twist;
  138.  
  139.         if (strncasecmp("rel", word, strlen(word)) != 0) {
  140.             printf("from requires 'abs' or 'rel' as ");
  141.             printf("a second argument.\n");
  142.         }
  143.         return TRUE;
  144.     }
  145.  
  146.  
  147.     /* Determine the number of steps necessary to move from the initial */
  148.     /* from point to the new from point.  If there is no change in */
  149.     /* location, use the twist value to determine the twist rate.  If */
  150.     /* there is no change in twist, quit the function. */
  151.     dist = fhypot((double) dx, fhypot((double) dy, (double) dz));
  152.  
  153.     if (dist == 0.0) {
  154.         if (dt == 0.0) {
  155.             return FALSE;
  156.         }
  157.         else {
  158.             steps = fabs(dt / (step * 500));
  159.         }
  160.     }
  161.     else {
  162.         steps = dist / step;
  163.     }
  164.  
  165.  
  166.     /* Calculate the steps sizes for x, y, z, and twist parameters. */
  167.     dx /= steps;
  168.     dy /= steps;
  169.     dz /= steps;
  170.     dt /= steps;
  171.  
  172.     /* Move the view, updating after each step */
  173.     twistf = (float) twist;
  174.     while ((steps >= 1.0) && current.fly_mode) {
  175.         /* Adjust the viewing parameters */
  176.         from[X] += (float) dx;
  177.         from[Y] += (float) dy;
  178.         from[Z] += (float) dz;
  179.         twistf += dt;
  180.         twist = (Angle) twistf;
  181.         steps -= 1.0;
  182.  
  183.         cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
  184.                    &rho, &theta, &phi);
  185.  
  186.         /* Redraw the window and check for any other pending events */
  187.         if (current.window != NULL) {
  188.             qenter(REDRAW, (short) current.active_id);
  189.         }
  190.         handle_event(windows);
  191.  
  192.         /* If the user terminated the fly-by, get out of here */
  193.         /* without any further changes. */
  194.         if (!current.fly_mode) return FALSE;
  195.     }
  196.  
  197.     /* If there was part of a step left over, adjust the final position */
  198.     /* and regenerate the image */
  199.     if (steps != 0.0) {
  200.         from[X] = fx;
  201.         from[Y] = fy;
  202.         from[Z] = fz;
  203.         twist = ft;
  204.         cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
  205.                    &rho, &theta, &phi);
  206.  
  207.         if (current.window != NULL) {
  208.             qenter(REDRAW, (short) current.active_id);
  209.         }
  210.         handle_event(windows);
  211.     }
  212.     
  213.     return FALSE;
  214. }
  215.  
  216.  
  217. int
  218. at_c(line)
  219.     char * line;
  220. {
  221.     char word[MAXLINELEN];
  222.     windat_t * window;
  223.     double nx, ny, nz;
  224.     float dx, dy, dz;
  225.     double dist;
  226.     int steps;
  227.     
  228.     /* Get the type of move and coordinate vector */
  229.     word[0] = '\0';
  230.     if (sscanf(line, "%s %f %f %f", word, &dx, &dy, &dz) != 4) {
  231.         printf("at requires four arguments:  type, x, y, z.\n");
  232.         return TRUE;
  233.     }
  234.  
  235.     /* Adjust the new vector based on the word...*/
  236.     if (strncasecmp("rel", word, strlen(word)) == 0) {
  237.         dx += at[X];
  238.         dy += at[Y];
  239.         dz += at[Z];
  240.     }
  241.     else if (strncasecmp("abs", word, strlen(word)) != 0) {
  242.         printf("at requires 'abs' or 'rel' as second argument.\n");
  243.         return TRUE;
  244.     }
  245.  
  246.     /* Calculate how to move */
  247.     dist = fhypot((double)(dx-at[X]), fhypot((double)(dy-at[Y]),
  248.                         (double)(dz-at[Z])));
  249.     nx = (dx - at[X]) / dist * step;
  250.     ny = (dy - at[Y]) / dist * step;
  251.     nz = (dz - at[Z]) / dist * step;
  252.  
  253.     /* Move the view, updating after each step */
  254.     for (steps = dist / step; (steps > 0.0) && current.fly_mode;
  255.          steps -= 1.0) {
  256.         at[X] += (float) nx;
  257.         at[Y] += (float) ny;
  258.         at[Z] += (float) nz;
  259.         cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
  260.                    &rho, &theta, &phi);
  261.  
  262.  
  263.         if (current.window != NULL) {
  264.             qenter(REDRAW, (short) current.active_id);
  265.         }
  266.         handle_event(windows);
  267.         if (!current.fly_mode) return FALSE;
  268.     }
  269.     at[X] = dx;
  270.     at[Y] = dy;
  271.     at[Z] = dz;
  272.     cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
  273.                &rho, &theta, &phi);
  274.  
  275.     if (current.window != NULL) {
  276.         qenter(REDRAW, (short) current.active_id);
  277.     }
  278.     handle_event(windows);
  279.     
  280.     return FALSE;
  281. }
  282.  
  283.  
  284. int
  285. step_c(line)
  286.     char * line;
  287. {
  288.     /* Get the new step size value */
  289.     if (sscanf(line, "%f", &step) != 1) {
  290.         printf("step requires one argument:  stepsize.\n");
  291.         return TRUE;
  292.     }
  293.  
  294.     return FALSE;
  295. }
  296.     
  297.  
  298. int
  299. twist_c(line)
  300.     char * line;
  301. {
  302.     float angle;
  303.     float twist_dist;
  304.     Angle new_twist;
  305.     int steps;
  306.     float nt;
  307.  
  308.     
  309.     /* Get the new twist angle value */
  310.     if (sscanf(line, "%f", &angle) != 1) {
  311.         printf("twist requires one argument:  angle.\n");
  312.         return TRUE;
  313.     }
  314.  
  315.  
  316.     /* Calculate the amount of change in twist required */
  317.     new_twist = (Angle) angle * 10;
  318.     twist_dist = new_twist - twist;
  319.     nt = (step * 500);
  320.     if (twist_dist < 0.0) nt = -nt;
  321.  
  322.  
  323.     /* Change the twist, updating after each step */
  324.     for (steps = (int) (twist_dist / nt);
  325.          (steps > 0) && current.fly_mode; steps--) {
  326.         twist += nt;
  327.  
  328.         if (current.window != NULL) {
  329.             qenter(REDRAW, (short) current.active_id);
  330.         }
  331.         handle_event(windows);
  332.         if (!current.fly_mode) return FALSE;
  333.     }
  334.  
  335.     if (twist != new_twist) {
  336.         twist = new_twist;
  337.         if (current.window != NULL) {
  338.             qenter(REDRAW, (short) current.active_id);
  339.         }
  340.         handle_event(windows);
  341.     }
  342.  
  343.     return FALSE;
  344. }
  345.  
  346.  
  347. int
  348. write_c(line)
  349.     char * line;
  350. {
  351.     /* Should provide single and auto options, file name, and optional */
  352.     /* count between frames */
  353.     return FALSE;
  354. }
  355.     
  356.  
  357. int
  358. reset_c(line)
  359.     char * line;
  360. {
  361.     do_reset(10);
  362.     return FALSE;
  363. }
  364.     
  365.  
  366. int
  367. point_mode(val)
  368.     int val;
  369. {
  370.     current.points = TRUE;
  371.     current.lines = FALSE;
  372.     current.polygons = FALSE;
  373.     qenter(REDRAW, (short) current.active_id);
  374.     return 1;
  375. }
  376.  
  377.  
  378. int
  379. lines_mode(val)
  380.     int val;
  381. {
  382.     current.points = FALSE;
  383.     current.lines = TRUE;
  384.     current.polygons = FALSE;
  385.     qenter(REDRAW, (short) current.active_id);
  386.     return 1;
  387. }
  388.  
  389.  
  390. int
  391. polygon_mode(val)
  392.     int val;
  393. {
  394.     current.points = FALSE;
  395.     current.lines = FALSE;
  396.     current.polygons = TRUE;
  397.     qenter(REDRAW, (short) current.active_id);
  398.     return 1;
  399. }
  400.  
  401.  
  402. int
  403. depth_mode(val)
  404.     int val;
  405. {
  406.     current.depth = !current.depth;
  407.     qenter(REDRAW, (short) current.active_id);
  408.     return 1;
  409. }
  410.  
  411.  
  412. int
  413. constant_mode(val)
  414.     int val;
  415. {
  416.     current.constant = TRUE;
  417.     qenter(REDRAW, (short) current.active_id);
  418.     return 1;
  419. }
  420.  
  421.  
  422. int
  423. gouraud_mode(val)
  424.     int val;
  425. {
  426.     current.constant = FALSE;
  427.     qenter(REDRAW, (short) current.active_id);
  428.     return 1;
  429. }
  430.  
  431.  
  432. int
  433. ortho_mode(val)
  434.     int val;
  435. {
  436.     current.ortho = TRUE;
  437.     qenter(REDRAW, (short) current.active_id);
  438.     return 1;
  439. }
  440.  
  441.  
  442. int
  443. persp_mode(val)
  444.     int val;
  445. {
  446.     current.ortho = FALSE;
  447.     qenter(REDRAW, (short) current.active_id);
  448.     return 1;
  449. }
  450.  
  451.  
  452. int
  453. at_point_tgl(val)
  454.     int val;
  455. {
  456.     current.at_point = !current.at_point;
  457.     qenter(REDRAW, (short) current.active_id);
  458.     return 1;
  459. }
  460.  
  461.  
  462. int
  463. palette_pick(val)
  464.     int val;
  465. {
  466.     switch (val) {
  467.     case 1:    /* from file */
  468.         build_colormap(LOAD_SPEC);
  469.         break;
  470.     case 2: /* gray */
  471.         build_colormap(GRAY_SPEC);
  472.         break;
  473.     case 3:    /* rainbow */
  474.         build_colormap(RBOW_SPEC);
  475.         break;
  476.     case 4: /* rgb */
  477.         build_colormap(RGB_SPEC);
  478.         break;
  479.     }
  480. }
  481.  
  482.  
  483. int
  484. axes_tgl(val)
  485.     int val;
  486. {
  487.     current.axes = !current.axes;
  488.     current.box = FALSE;
  489.     qenter(REDRAW, (short) current.active_id);
  490.     return 1;
  491. }
  492.  
  493.  
  494.  
  495. int
  496. box_tgl(val)
  497.     int val;
  498. {
  499.     current.axes = FALSE;
  500.     current.box = !current.box;
  501.     qenter(REDRAW, (short) current.active_id);
  502.     return 1;
  503. }
  504.  
  505.  
  506. int
  507. labels_tgl(val)
  508.     int val;
  509. {
  510.     current.labels = !current.labels;
  511.     qenter(REDRAW, (short) current.active_id);
  512.     return 1;
  513. }
  514.  
  515.  
  516. int
  517. outlines_tgl(val)
  518.     int val;
  519. {
  520.     if (current.polygons) {
  521.         current.outlines = !current.outlines;
  522.         qenter(REDRAW, (short) current.active_id);
  523.     }
  524.     else
  525.         if (current.outlines)
  526.             current.outlines = !current.outlines;
  527.     return 1;
  528. }
  529.  
  530.  
  531. int
  532. forward(val)
  533.     int val;
  534. {
  535.     image_t ** image;
  536.  
  537.     animation.forward = -1;
  538.     animation.reverse = 0;
  539.  
  540.     return 1;
  541. }
  542.  
  543.  
  544. int
  545. forward1(val)
  546.     int val;
  547. {
  548.     animation.forward = 1;
  549.     animation.reverse = 0;
  550.  
  551.     return 1;
  552. }
  553.  
  554.  
  555. int
  556. stop(val)
  557.     int val;
  558. {
  559.     animation.forward = 0;
  560.     animation.reverse = 0;
  561.  
  562.     return 1;
  563. }
  564.  
  565.  
  566. int
  567. reverse1(val)
  568.     int val;
  569. {
  570.     image_t * image;
  571.  
  572.     animation.forward = 0;
  573.     animation.reverse = 1;
  574.  
  575.     return 1;
  576. }
  577.  
  578.  
  579. int
  580. reverse(val)
  581.     int val;
  582. {
  583.     image_t * image;
  584.  
  585.     animation.forward = 0;
  586.     animation.reverse = -1;
  587.  
  588.     return 1;
  589. }
  590.  
  591.  
  592. int
  593. do_fly(val)
  594.     int val;
  595. {
  596.     if (current.fly_mode) {
  597.         current.fly_mode = FALSE;
  598.     }
  599.     else {
  600.         current.fly_mode = TRUE;
  601.         if (args_found_arg(args, "fly")) {
  602.             if (read_fly_file(flyfile)) {
  603.                 printf("\nERROR:  Problem reading flyfile '%s'.\n",
  604.                     flyfile);
  605.                 exit(-1);
  606.             }
  607.             else {
  608.             }
  609.         }
  610.         else {
  611.             printf("\nPlease specify flyfile on command line\n");
  612.             printf("using the '-fly' switch for this option.\n");
  613.         }
  614.     }
  615.  
  616.     /* Turn off the flying now that we are done */
  617.     current.fly_mode = FALSE;
  618.     return 1;
  619. }
  620.  
  621.  
  622. int
  623. do_redraw(val)
  624.     int val;
  625. {
  626.     qenter(REDRAW, (short) current.active_id);
  627.     return 1;
  628. }
  629.  
  630.  
  631. int
  632. do_reset(val)
  633.     int val;
  634. {
  635.     initialize(TRUE);
  636.     qenter(REDRAW, (short) current.active_id);
  637.     return 1;
  638. }
  639.  
  640.  
  641. int
  642. do_pop(val)
  643.     int val;
  644. {
  645.     winpop();
  646.     return 1;
  647. }
  648.  
  649.  
  650. int
  651. write_hdf(val)
  652.     int val;
  653. {
  654.     unsigned char *buff;
  655.     int depth, ret, num_bytes;
  656.     long xsize, ysize;
  657.     long x, y;
  658.     Screencoord sx1,sy1,sx2,sy2;
  659.     int i, j;
  660.     char local_palette[256*3];
  661.  
  662.     /* pop the current window to the top of the screen */
  663.     winset(current.active_id); 
  664.     winpop();
  665.      getsize(&x, &y);
  666.  
  667.     /* Calculate the number of bytes required for the screen */
  668.     getviewport(&sx1,&sx2,&sy1,&sy2);
  669.     xsize = (sx2 - sx1) + 1;
  670.     ysize = (sy2 - sy1) + 1;
  671.  
  672.     num_bytes = xsize * ysize * sizeof(char);
  673.     buff = (unsigned char *)malloc(num_bytes);
  674.     if (!buff) {
  675.         printf("%s: Not enough memory\n",main_image.ris8out);
  676.         exit(1);
  677.     }
  678.  
  679.     /* Copy the palette to the proper format for DFR8setpalette */
  680.     for (i = 0; i < 256; i++) {
  681.         for (j = 0; j < 3; j++) {
  682.             local_palette[i*3+j] = palette[i][j];
  683.         }
  684.     }
  685.  
  686.     /* Read the screen and write it to the hdf file */
  687.     read_scr(&xsize,&ysize,buff);
  688.     DFR8setpalette(local_palette); 
  689.     ret = DFR8putimage(main_image.ris8out,buff,xsize,ysize,11);
  690.     if (ret) {
  691.         printf("%s: Error with DFR8putimage\n",main_image.ris8out);
  692.         exit(1);
  693.     }
  694. }
  695.  
  696.  
  697. int
  698. read_scr(xsiz,ysiz,ibuff)
  699.     long *xsiz,*ysiz;
  700.     unsigned char *ibuff;
  701. {
  702.     Screencoord sx1,sy1,sx2,sy2;
  703.     Coord rx1,ry1,rx2,ry2;
  704.     Colorindex *row_cols;
  705.     int num_bytes;
  706.     register int i,j;
  707.     Icoord ix;
  708.     short lx;
  709.     long jrp;
  710.     unsigned char *buf_ptr;
  711.     static float idmatrix[4][4] = {
  712.             1.0, 0.0, 0.0, 0.0,
  713.             0.0, 1.0, 0.0, 0.0,
  714.             0.0, 0.0, 1.0, 0.0,
  715.             0.0, 0.0, 0.0, 1.0};
  716.  
  717.  
  718.     getviewport(&sx1,&sx2,&sy1,&sy2);
  719.  
  720.     *xsiz = (sx2 - sx1) + 1;
  721.     *ysiz = (sy2 - sy1) + 1;
  722.  
  723.     rx1 = (Coord)sx1 - 0.5;
  724.     ry1 = (Coord)sy1 - 0.5;
  725.     rx2 = (Coord)sx2 + 0.5;
  726.     ry2 = (Coord)sy2 + 0.5;
  727.  
  728.     pushmatrix();
  729.     pushviewport();
  730.     loadmatrix(idmatrix);
  731.     ortho2(rx1,rx2,ry1,ry2);
  732.  
  733.     lx = (short)(*xsiz);
  734.     ix = sx1;
  735.     buf_ptr = &ibuff[0];
  736.  
  737.     num_bytes = lx * sizeof(Colorindex);
  738.     row_cols = (Colorindex *)malloc(num_bytes);
  739.     if (!row_cols){
  740.         puts("Not enough memory for row_cols");
  741.         exit(1);
  742.     }
  743.  
  744.     readsource(SRC_FRONT);
  745.     for(j=sy2; j >= sy1; j--){
  746.         cmov2i(ix,j);
  747.         jrp = readpixels(lx,row_cols);
  748.         for(i=0; i<lx; i++)
  749.             *buf_ptr++ = (unsigned char)(row_cols[i] - SPEC_BASE);
  750.     }
  751.  
  752.     free(row_cols);
  753.  
  754.     popviewport();
  755.     popmatrix();
  756.  
  757.     return(0);
  758. }
  759.